package edu.scau.mis.pos.service.impl;


import edu.scau.mis.core.utils.DateUtils;
import edu.scau.mis.pos.entity.PosCategory;
import edu.scau.mis.pos.entity.PosItem;
import edu.scau.mis.pos.entity.PosOrder;
import edu.scau.mis.pos.entity.PosOrderItem;
import edu.scau.mis.pos.mapper.CategoryMapper;
import edu.scau.mis.pos.mapper.ItemMapper;
import edu.scau.mis.pos.mapper.OrderItemMapper;
import edu.scau.mis.pos.mapper.OrderMapper;
import edu.scau.mis.pos.service.IOrderItemService;
import edu.scau.mis.pos.vo.DashboardVo;
import edu.scau.mis.pos.vo.OrderItemVo;
import javafx.geometry.Pos;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.*;

/**
 * (PosOrderItem)表服务实现类
 *
 * @author makejava
 * @since 2021-11-04 23:21:23
 */
@Service("orderItemService")
public class OrderItemServiceImpl implements IOrderItemService {
    Map<String,List<PosOrderItem>> mapCache = new HashMap<>(); //缓存数据
    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ItemMapper itemMapper;


    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private CategoryMapper categoryMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param orderItemId 主键
     * @return 实例对象
     */
    @Override
    public PosOrderItem queryById(@RequestBody Integer orderItemId) {
        return this.orderItemMapper.queryById(orderItemId);
    }

    /**
     * 分页查询
     *
     * @param posOrderItem 筛选条件
     * @return 查询结果
     */
    @Override
    public List<PosOrderItem> queryAll(@RequestBody PosOrderItem posOrderItem) {
        return this.orderItemMapper.queryAll(posOrderItem);
    }

    /**
     * 新增数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem insert(@RequestBody PosOrderItem posOrderItem) {
        this.orderItemMapper.insert(posOrderItem);
        return posOrderItem;
    }
    /**
     * 修改数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem update(PosOrderItem posOrderItem) {
        this.orderItemMapper.update(posOrderItem);
        return this.queryById(posOrderItem.getOrderItemId());
    }

    /**
     * 通过主键删除数据
     *
     * @param orderItemId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer orderItemId) {
        return this.orderItemMapper.deleteById(orderItemId) > 0;
    }

    /**
     * 步骤1：根据读者证号查询读者信息和业务关键信息
     * @param orderNo 读者证号
     * @return 读者信息，借阅中图书数量，超期未还数
     */
    @Override
    public Map<String, Object> getOrderAndBuyInformationByOrderNo(@RequestBody String orderNo) {
        this.createMapCache(orderNo);  // 创建借阅数据缓存
        Map<String, Object> info =  new HashMap<String,Object>();
        PosOrder posOrder = this.orderMapper.queryOrderWithItemListByOrderNo(orderNo);
        int quantity = posOrder.getItemList().size();
        info.put("order",posOrder);
        info.put("quantity",quantity);
        System.out.println("输出的库存："+quantity);
        return info;
    }

    /**
     * 生成缓存数据_内存存储_HashMap
     * 步骤1_依赖方法1
     * @param orderNo
     * @return
     */
    private Map<String, List<PosOrderItem>> createMapCache(@RequestBody String orderNo){
        List<PosOrderItem> orderItemList = new ArrayList<>();
        mapCache.put(orderNo,orderItemList);
        return mapCache;
    }

    /**
     * 得到借阅中图书列表
     * 步骤1_依赖方法2
     * @param orderNo
     * @return
     */
    private List<PosItem> getBuyingItemOfOrder(@RequestBody String orderNo){
        PosOrder posOrder = this.orderMapper.queryOrderWithItemListByOrderNo(orderNo);
        return posOrder.getItemList();

    }

    /**
     * 步骤2：添加图书到待借图书列表
     * @param orderItemVo 传值对象
     * 封装了readerNo和isbn
     * @return 待借图书列表
     */
    public List<PosItem> enterLineOrderItem(@RequestBody OrderItemVo orderItemVo) {
        String orderNo = orderItemVo.getOrderNo();
        int orderId = this.orderMapper.queryIdByOrderNo(orderNo).getOrderId();
        PosItem posItem = this.itemMapper.queryItemByCode(orderItemVo.getCode());
        PosOrderItem posOrderItem = new PosOrderItem();
        posOrderItem.setOrderId(orderId);
        posOrderItem.setItemId(posItem.getItemId());
        posOrderItem.setSalePrice(posItem.getPrice()*Double.parseDouble(orderItemVo.getQuantity()));
        posOrderItem.setQuantity(orderItemVo.getQuantity());

        int itemQuantity=Integer.parseInt(orderItemVo.getQuantity());
        int exist=Integer.parseInt(posItem.getInventory());
        int newInventory=exist-itemQuantity;

        posItem.setInventory(String.valueOf(newInventory));
        itemMapper.update(posItem);
        List<PosOrderItem> orderItemList = mapCache.get(orderNo);
        orderItemList.add(posOrderItem);
        mapCache.put(orderNo,orderItemList);
        return this.getEnterItemList(orderNo);
    }

    @Override
    public String queryExistOrderItemQuantity(PosOrderItem posOrderItem) {
        String totalOrderItemQuantity=this.orderItemMapper.queryExistOrderItemQuantity(posOrderItem);
        return totalOrderItemQuantity;
    }

    /**
     * 根据readerNo从缓存加载bookIds，得到待借图书集合
     * 步骤2_依赖方法2
     * @param orderNo 读者证号
     * @return 待借图书集合
     */
    private List<PosItem> getEnterItemList(@RequestBody String orderNo){
        List<PosItem> enterItemList = new ArrayList<>();
        List<PosOrderItem> orderItemList = mapCache.get(orderNo);
        for(PosOrderItem orderItem : orderItemList){
            enterItemList.add(this.itemMapper.queryById(orderItem.getItemId()));
        }
        return enterItemList;
    }


    /**
     * 步骤3：确认借书
     * @param orderNo 读者证号
     */
    @Override
    public boolean ConfirmBuyItem(@RequestBody String orderNo) {
        boolean flag = false;
        List<PosOrderItem> orderItemList = mapCache.get(orderNo);
        int availableQuantity = 10 - getBuyingItemOfOrder(orderNo).size();
        int quantity = orderItemList.size();
        if(quantity > 0 && quantity <= availableQuantity){
            flag = this.orderItemMapper.insertBatch(orderItemList) > 0;

            int orderId = this.orderMapper.queryIdByOrderNo(orderNo).getOrderId();
            PosOrder posOrder=orderMapper.queryById(orderId);

            Date date = DateUtils.getNowDate();
            Integer tolQuantity=orderItemMapper.queryExistOrderTolQuantity(orderId);
            Double tolPrice=orderItemMapper.queryExistOrderTolPrice(orderId);
            posOrder.setTotalquantity(tolQuantity.toString());
            posOrder.setTotalamount(tolPrice.toString());
            posOrder.setSaleDatetime(date);
            orderMapper.update(posOrder);


//            this.orderItemMapper.insertOrUpdateBatch(orderItemList);
            this.removeMapCache(orderNo);
        }
        return flag;


    }



    /**
     * 删除缓存数据_内存存储_HashMap
     * 步骤3_依赖方法1
     * @param orderNo
     */
    private void removeMapCache(@RequestBody String orderNo) {
        Iterator<Map.Entry<String,List<PosOrderItem>>> iterator = mapCache.entrySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next().getKey();
            if (orderNo.equals(key)) {
                iterator.remove();
            }
        }
    }

    /**
     * 新增缓存value元素
     * @param orderNo
     * @param posOrderItem
     */
    private void putCache(@RequestBody String orderNo,PosOrderItem posOrderItem){
        if(mapCache.containsKey(orderNo)){
            mapCache.get(orderNo).add(posOrderItem);
        }
    }

    /**
     * 按图书类别id统计借阅数
     * @return 记录数
     */
    @Override
    public List<DashboardVo> CountByCategoryId(){
        List<PosCategory> categoryList = this.categoryMapper.queryAll(new PosCategory());
        List<DashboardVo> dashboardVoList = new ArrayList<>();
        for(PosCategory posCategory : categoryList){
            DashboardVo dashboardVo = new DashboardVo();
            long count = this.orderItemMapper.countByCategoryId(posCategory.getCategoryId());
            String name = posCategory.getCategoryName();
            dashboardVo.setValue(count);
            dashboardVo.setName(name);
            dashboardVoList.add(dashboardVo);
        }
        return dashboardVoList;
    }

}
